﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Windows.Forms;
using CookComputing.XmlRpc;
using ASRSubsDownloader.Common;
using ASRSubsDownloader.Subtitles;

namespace ASRSubsDownloader.Forms
{
    public partial class MoviesForm : Form
    {
        private string currentFilePath;
        private IOpenSubtitles openSubClient;
        public MoviesForm()
        {
            InitializeComponent();
        }

        private void MoviesForm_Shown(object sender, EventArgs e)
        {
            //var thr = new System.Threading.Thread(showSplash);
            //thr.Start();
            Width = 995;
            cbHasSub.SelectedIndex = 0;
            dtGridMovir.DataSource = Config.FilesCache.Files;
            //thr.Abort();
        }


        public void showSplash()
        {
            var frm = new Splash();
            frm.ShowDialog();
        }


        private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            //var thr = new System.Threading.Thread(showSplash);
            //thr.Start();
            ((DataGridView)sender).CellDoubleClick -= dataGridView1_CellDoubleClick;
            try
            {
                Width = 1419;
                Deactivatecontrols();
                getSubtitles(dtGridMovir.Rows[e.RowIndex].Cells[0].Value.ToString());
                Deactivatecontrols(true);
            }
            catch (UnauthorizedAccessException ex)
            {
                MessageBox.Show("Acesso ao arquivo negado, por favor verifique se o arquivo não é somente leitura e que você tem permissão de editá-lo");
                Deactivatecontrols(true);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro ao buscar legendas!");
                Deactivatecontrols(true);
            }
            ((DataGridView)sender).CellDoubleClick += dataGridView1_CellDoubleClick;
            //if (thr.IsAlive)
            //    thr.Abort();
        }

        private void cbHasSub_SelectedIndexChanged(object sender, EventArgs e)
        {
            dtGridMovir.DataSource = null;
            dtGridMovir.Rows.Clear();
            dtGridMovir.DataSource =
                Config.FilesCache.Files.Where(x => ((x.HasSubtitle && cbHasSub.SelectedIndex == 1) ||
                                                               (!x.HasSubtitle && cbHasSub.SelectedIndex == 2) ||
                                                               cbHasSub.SelectedIndex == 0) && (x.FileName.ToLower().Contains(txtNome.Text.ToLower()))).ToList();
            dtGridMovir.Columns[0].Width = 800;
        }

        private void txtNome_KeyUp(object sender, KeyEventArgs e)
        {
            dtGridMovir.DataSource = null;
            dtGridMovir.Rows.Clear();
            dtGridMovir.DataSource =
                Config.FilesCache.Files.Where(x => ((x.HasSubtitle && cbHasSub.SelectedIndex == 1) ||
                                                               (!x.HasSubtitle && cbHasSub.SelectedIndex == 2) ||
                                                               cbHasSub.SelectedIndex == 0) && (x.FileName.ToLower().Contains(txtNome.Text.ToLower()))).ToList();
            dtGridMovir.Columns[0].Width = 800;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Hide();
        }

        private void Deactivatecontrols(bool state = false)
        {
            foreach (Control control in Controls)
            {
                control.Enabled = state;
            }
        }

        public void ReOpenConnection(bool forceReopen = false)
        {
            if (openSubClient == null || forceReopen)
            {
                openSubClient = XmlRpcProxyGen.Create<IOpenSubtitles>();
                var res = openSubClient.LogIn(Config.OpenSubtitlesUserName, Config.OpenSubtitlesPassword,
                                              Config.Language, Config.OpenSubtitlesUserAgent);
                Config.SecurityToken = res["token"].ToString();
            }
        }


        private struct Subtitle
        {
            public string IDSubtitleFile { get; set; }
            public string SubFileName { get; set; }
            public int SubDownloadsCnt { get; set; }
        }

        public void getSubtitles(string FileName)
        {
            if (openSubClient == null)
                ReOpenConnection();
            Stream file = null;
            try
            {
                byte[] hash = GetHash.Main.ComputeHash(FileName);
                var strHash = GetHash.Main.ToHexadecimal(hash);
                currentFilePath = FileName;
                file = File.Open(FileName, FileMode.Open, FileAccess.Read);
                var parameters = new XmlRpcStruct();
                parameters.Add("sublanguageid", Config.Language);
                parameters.Add("moviehash", strHash);
                parameters.Add("moviebytesize", file.Length);
                var param = new[] { parameters };
                var res = openSubClient.SearchSubtitles(Config.SecurityToken, param);
                dtGridSubs.DataSource = null;
                var dtSource = new List<Subtitle>();
                if (!(res["data"] is bool && (!(bool)res["data"])))
                {
                    foreach (var re in res["data"] as IList<object>)
                    {
                        var sub = re as XmlRpcStruct;
                        var subSource = new Subtitle();
                        subSource.IDSubtitleFile = sub["IDSubtitleFile"].ToString();
                        subSource.SubFileName = sub["SubFileName"].ToString();
                        int a;
                        if (int.TryParse(sub["SubDownloadsCnt"].ToString(), out a))
                            subSource.SubDownloadsCnt = a;
                        dtSource.Add(subSource);
                    }
                    
                    dtSource = dtSource.OrderByDescending(x => x.SubDownloadsCnt).ToList();
                    dtGridSubs.DataSource = dtSource;
                    dtGridSubs.Visible = true;
                    dtGridSubs.Columns[0].Visible = false;
                }
            }
            finally
            {
                if (file != null)
                    file.Close();
            }
        }

        private MemoryStream GetSubStream(int Id)
        {
            var res = openSubClient.DownloadSubtitles(Config.SecurityToken,
                                                      new int[1] { Id });

            byte[] encodedDataAsBytes = System.Convert.FromBase64String((String)((XmlRpcStruct)((object[])res["data"])[0])["data"]);
            using (var ms = new MemoryStream(encodedDataAsBytes))
            {
                int msgLength = BitConverter.ToInt32(encodedDataAsBytes, 0);
                byte[] buffer = new byte[msgLength];

                ms.Position = 0;
                using (var zip = new GZipStream(ms, CompressionMode.Decompress))
                {
                    zip.Read(buffer, 0, buffer.Length);
                    return new MemoryStream(buffer);
                }
            }
        }


        private void dtGridSubs_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            var memoryStream = GetSubStream(Convert.ToInt32(dtGridSubs.Rows[e.RowIndex].Cells[0].Value));
            
            if (File.Exists(FileHelper.FileHelper.GetFileNameWithOutExtension(currentFilePath) + ".srt"))
                File.Delete(FileHelper.FileHelper.GetFileNameWithOutExtension(currentFilePath) + ".srt");
            var fs = new FileStream(FileHelper.FileHelper.GetFileNameWithOutExtension(currentFilePath) + ".srt", FileMode.OpenOrCreate);
            memoryStream.WriteTo(fs);
            memoryStream.Flush();
            memoryStream.Close();
            fs.Close();
            
            MessageBox.Show("Legenda baixada com sucesso!");
            Width = 995;
            dtGridSubs.Hide();
        }

        private void dtGridMovir_SelectionChanged(object sender, EventArgs e)
        {
            Width = 995;
            dtGridSubs.Hide();
        }

        private void removerDaListaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var fileName = dtGridMovir.SelectedRows[0].Cells[0].Value.ToString();
            Config.BlackList.Files.Add(new FileHelper.File() {FileName = fileName, HasSubtitle = false});
            Config.FilesCache.Files.RemoveAll(x => x.FileName == fileName);
            dtGridMovir.DataSource =
               Config.FilesCache.Files.Where(x => ((x.HasSubtitle && cbHasSub.SelectedIndex == 1) ||
                                                              (!x.HasSubtitle && cbHasSub.SelectedIndex == 2) ||
                                                              cbHasSub.SelectedIndex == 0) && (x.FileName.ToLower().Contains(txtNome.Text.ToLower()))).ToList();
            
        }

        private void dtGridMovir_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                int rowSelected = e.RowIndex;
                if (e.RowIndex != -1)
                {
                    dtGridMovir.Rows[rowSelected].Selected = true;
                }
                var screenCors = Cursor.Position;
                contextMenuStrip1.Show(screenCors.X, screenCors.Y);
            }
        }

        private void abrirPastaNoWindowsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var fileName = dtGridMovir.SelectedRows[0].Cells[0].Value.ToString();
            string args = string.Format("/Select, {0}", fileName);

            var pfi = new ProcessStartInfo("Explorer.exe", args);
            Process.Start(pfi);
        }

        private void procurarLegendasToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var fileName = dtGridMovir.SelectedRows[0].Cells[0].Value.ToString();
            dtGridMovir.CellDoubleClick -= dataGridView1_CellDoubleClick;
            try
            {
                Width = 1419;
                Deactivatecontrols();
                getSubtitles(fileName);
                Deactivatecontrols(true);
            }
            catch (UnauthorizedAccessException ex)
            {
                MessageBox.Show("Acesso ao arquivo negado, por favor verifique se o arquivo não é somente leitura e que você tem permissão de editá-lo");
                Deactivatecontrols(true);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro ao buscar legendas!");
                Deactivatecontrols(true);
            }
            dtGridMovir.CellDoubleClick += dataGridView1_CellDoubleClick;
        }
    }
}
